<template>
  <div class="advanced-search">
    <h2 class="search-title">高级搜索 (ElasticSearch)</h2>

    <div class="search-form">
      <div class="search-input-container">
        <input
          type="text"
          v-model="searchQuery"
          @input="debouncedSearch"
          placeholder="输入关键词搜索..."
          class="search-input"
        />
        <button class="search-button" @click="performSearch">
          <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <circle cx="11" cy="11" r="8"></circle>
            <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
          </svg>
        </button>
      </div>

      <div class="search-options">
        <div class="option-group">
          <label class="option-label">搜索范围:</label>
          <div class="checkbox-group">
            <label class="checkbox-label">
              <input type="checkbox" v-model="searchOptions.fields.title"> 标题
            </label>
            <label class="checkbox-label">
              <input type="checkbox" v-model="searchOptions.fields.title"> 摘要
            </label>
            <label class="checkbox-label">
              <input type="checkbox" v-model="searchOptions.fields.content"> 内容
            </label>
            <label class="checkbox-label">
              <input type="checkbox" v-model="searchOptions.fields.tags"> 标签
            </label>
          </div>
        </div>

        <div class="option-group">
          <label class="option-label">搜索设置:</label>
          <div class="checkbox-group">
            <label class="checkbox-label">
              <input type="checkbox" v-model="searchOptions.fuzzy"> 模糊匹配
            </label>
            <label class="checkbox-label">
              <input type="checkbox" v-model="searchOptions.highlight"> 高亮显示
            </label>
          </div>
        </div>
      </div>
    </div>

    <div class="search-status" v-if="searchPerformed">
      <span v-if="isSearching">正在搜索...</span>
      <span v-else>找到 {{ totalResults }} 条结果 ({{ searchTime }}ms)</span>
    </div>

    <div class="search-results" v-if="searchResults.length > 0">
      <div v-for="result in searchResults" :key="result._id" class="result-item card">
        <h3 class="result-title">
          <router-link :to="`/posts/${result._id}`">
            <span v-if="result.highlight && result.highlight.title"
                  v-html="result.highlight.title[0]"></span>
            <span v-else>{{ result._source.title }}</span>
          </router-link>
        </h3>

        <div class="result-excerpt" v-if="result.highlight && result.highlight.content"
             v-html="'...' + result.highlight.content[0] + '...'"></div>
        <div class="result-excerpt" v-else>{{ result._source.excerpt }}</div>

        <div class="result-meta">
          <div class="result-tags">
            <span v-for="tag in result._source.tags" :key="tag" class="result-tag">{{ tag }}</span>
          </div>
          <div class="result-score">相关度: {{ result._score.toFixed(1) }}</div>
        </div>
      </div>
    </div>

    <div class="no-results" v-else-if="searchPerformed && !isSearching">
      <p>未找到与 "{{ searchQuery }}" 相关的内容</p>
      <div class="search-suggestions">
        <h4>建议：</h4>
        <ul>
          <li>检查拼写是否正确</li>
          <li>尝试使用不同的关键词</li>
          <li>尝试更广泛的搜索条件</li>
          <li>减少搜索词数量</li>
        </ul>
      </div>
    </div>

    <div class="search-explanation">
      <h3>关于ElasticSearch搜索</h3>
      <p>
        本示例展示了ElasticSearch的基本用法。ElasticSearch是一个分布式、开源的搜索和分析引擎，
        基于Apache Lucene构建。它能够提供全文搜索、结构化搜索、分析及其他功能。
      </p>
      <p>
        <strong>注意：</strong> 实际项目中，ElasticSearch应该部署在服务器端，
        并通过API接口提供搜索功能。本示例仅用于演示目的，使用前端模拟数据。
      </p>
      <div class="feature-list">
        <h4>ElasticSearch主要特性:</h4>
        <ul>
          <li>全文搜索与分析</li>
          <li>分布式架构，高可用性</li>
          <li>多租户功能</li>
          <li>实时搜索和分析</li>
          <li>丰富的查询DSL</li>
          <li>RESTful API</li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue';
import { searchContent } from '../services/elasticSearchService';

// 搜索状态
const searchQuery = ref('');
const searchResults = ref([]);
const isSearching = ref(false);
const searchPerformed = ref(false);
const searchTime = ref(0);
const totalResults = ref(0);

// 搜索选项
const searchOptions = reactive({
  fields: {
    title: true,
    content: true,
    tags: true
  },
  fuzzy: true,
  highlight: true,
  from: 0,
  size: 10
});

// 创建防抖函数
const debounce = (fn, delay) => {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
};

// 防抖搜索
const debouncedSearch = debounce(() => {
  if (searchQuery.value.length > 1) {
    performSearch();
  }
}, 500);

// 执行搜索
const performSearch = async () => {
  if (!searchQuery.value.trim()) {
    searchResults.value = [];
    searchPerformed.value = false;
    return;
  }

  isSearching.value = true;
  searchPerformed.value = true;

  try {
    // 构建搜索字段
    const fields = [];
    if (searchOptions.fields.title) fields.push('title^2'); // ^2表示权重为2
    if (searchOptions.fields.content) fields.push('content');
    if (searchOptions.fields.tags) fields.push('tags^3'); // 标签匹配权重更高

    // 构建搜索选项
    const options = {
      fields,
      fuzziness: searchOptions.fuzzy ? 'AUTO' : 0,
      highlight: searchOptions.highlight,
      from: searchOptions.from,
      size: searchOptions.size
    };

    // 执行搜索
    const startTime = performance.now();
    const response = await searchContent(searchQuery.value, options);
    const endTime = performance.now();

    // 更新结果
    searchResults.value = response.hits.hits;
    totalResults.value = response.hits.total.value;
    searchTime.value = Math.round(endTime - startTime);
  } catch (error) {
    console.error('Search error:', error);
    searchResults.value = [];
    totalResults.value = 0;
  } finally {
    isSearching.value = false;
  }
};

// 加载示例搜索
onMounted(() => {
  // 自动执行一个示例搜索
  searchQuery.value = 'React';
  performSearch();
});
</script>

<style scoped>
.advanced-search {
  max-width: 800px;
  margin: 0 auto;
  padding: 2rem 0;
}

.search-title {
  font-size: 1.75rem;
  margin-bottom: 1.5rem;
}

.search-form {
  margin-bottom: 2rem;
}

.search-input-container {
  display: flex;
  margin-bottom: 1rem;
}

.search-input {
  flex: 1;
  padding: 0.75rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: 4px 0 0 4px;
  font-size: 1rem;
  background-color: var(--color-card);
  color: var(--color-text);
}

.search-button {
  background-color: var(--color-primary);
  color: white;
  border: none;
  border-radius: 0 4px 4px 0;
  padding: 0 1rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s;
}

.search-button:hover {
  background-color: var(--color-secondary);
}

.search-options {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin-top: 0.5rem;
}

.option-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.option-label {
  font-weight: 500;
  color: var(--color-text-light);
  font-size: 0.875rem;
}

.checkbox-group {
  display: flex;
  gap: 1rem;
}

.checkbox-label {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.875rem;
  color: var(--color-text);
  cursor: pointer;
}

.search-status {
  margin-bottom: 1.5rem;
  font-size: 0.875rem;
  color: var(--color-text-light);
}

.search-results {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  margin-bottom: 2rem;
}

.result-item {
  padding: 1.5rem;
  background-color: var(--color-card);
  border-radius: var(--radius-md);
  box-shadow: 0 2px 8px var(--color-shadow);
  transition: transform 0.2s, box-shadow 0.2s;
}

.result-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px var(--color-shadow);
}

.result-title {
  font-size: 1.25rem;
  margin-bottom: 0.75rem;
}

.result-title a {
  color: var(--color-text);
  text-decoration: none;
}

.result-title a:hover {
  color: var(--color-primary);
}

.result-excerpt {
  font-size: 0.9rem;
  margin-bottom: 1rem;
  color: var(--color-text-light);
  line-height: 1.5;
}

.result-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.result-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.result-tag {
  padding: 0.25rem 0.5rem;
  background-color: var(--color-hover);
  border-radius: 4px;
  font-size: 0.75rem;
  color: var(--color-primary);
}

.result-score {
  font-size: 0.75rem;
  color: var(--color-text-light);
}

.no-results {
  background-color: var(--color-card);
  padding: 1.5rem;
  border-radius: var(--radius-md);
  text-align: center;
  margin-bottom: 2rem;
  border: 1px solid var(--color-border);
}

.search-suggestions {
  margin-top: 1rem;
  text-align: left;
  max-width: 400px;
  margin-left: auto;
  margin-right: auto;
}

.search-suggestions h4 {
  font-size: 1rem;
  margin-bottom: 0.5rem;
}

.search-suggestions ul {
  padding-left: 1.5rem;
}

.search-suggestions li {
  margin-bottom: 0.25rem;
  font-size: 0.875rem;
  color: var(--color-text-light);
}

.search-explanation {
  background-color: var(--color-card);
  padding: 1.5rem;
  border-radius: var(--radius-md);
  margin-top: 2rem;
  border: 1px solid var(--color-border);
}

.search-explanation h3 {
  font-size: 1.25rem;
  margin-bottom: 1rem;
}

.search-explanation p {
  margin-bottom: 1rem;
  line-height: 1.5;
  font-size: 0.9rem;
}

.feature-list {
  margin-top: 1rem;
}

.feature-list h4 {
  font-size: 1rem;
  margin-bottom: 0.5rem;
}

.feature-list ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.5rem;
  padding-left: 1.5rem;
}

.feature-list li {
  font-size: 0.875rem;
}

/* 高亮样式 */
:deep(em) {
  background-color: var(--color-mark-bg);
  font-style: normal;
  padding: 0 0.2rem;
  border-radius: 2px;
}

@media (max-width: 768px) {
  .search-options {
    flex-direction: column;
    gap: 1rem;
  }

  .checkbox-group {
    flex-wrap: wrap;
  }

  .result-meta {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
  }

  .feature-list ul {
    grid-template-columns: 1fr;
  }
}
</style>
